'abuvelocity.monkey by Belimoth
Strict
Import abu.abutime
Import abucomponent
'TODO
'	implement UNIT_ constants

Interface IVelocity
	Method xVelocity:Float() Property
	Method xVelocity:Void(xVelocityNew:Float) Property
	Method yVelocity:Float() Property
	Method yVelocity:Void(yVelocityNew:Float) Property
	
	Method xAcceleration:Float() Property
	Method xAcceleration:Void(xAccelerationNew:Float) Property
	Method yAcceleration:Float() Property
	Method yAcceleration:Void(yAccelerationNew:Float) Property
	
	Method xMaxVelocity:Float() Property
	Method yMaxVelocity:Float() Property
	Method SetMaxVelocity:Void(x:Float, y:Float)
	
	Method xDisplacement:Int() Property
	Method yDisplacement:Int() Property
End



Class Velocity Implements IVelocity, IJuggleable

Public
	Method New()
		juggler.Add(Self)
	End
	
	Method Destroy:Void()
		juggler.Remove(Self)
	End
	
	'Implements IJuggleable
	Method Active:Bool() Property Return True End												'Return Not(owner._markedForDeletion)
	
	Method Update:Void(timePassed:Int = 0)		'frames only for now
		_xVelocity += _xAcceleration
		_yVelocity += _yAcceleration
		'_xVelocity = Max( -_xMaxVelocity, Min(_xMaxVelocity, _xVelocity) )					'put this back in when max and min values are initialized correctly
		'_yVelocity = Max( -_yMaxVelocity, Min(_yMaxVelocity, _yVelocity) )					'put this back in when max and min values are initialized correctly
		_xDisplacement = Int(_xVelocity)												'TODO incoporate units and time
		_yDisplacement = Int(_yVelocity)												'TODO incoporate units and time
	End
	
	'Implements IVelocity
	Method xVelocity:Float() Property															Return _xVelocity														End
	Method xVelocity:Void(xVelocityNew:Float) Property											_xVelocity = xVelocityNew												End
	Method yVelocity:Float() Property															Return _yVelocity														End
	Method yVelocity:Void(yVelocityNew:Float) Property											_yVelocity = yVelocityNew												End
	
	Method xAcceleration:Float() Property														Return _xAcceleration													End
	Method xAcceleration:Void(xAccelerationNew:Float) Property									_xAcceleration = xAccelerationNew										End
	Method yAcceleration:Float() Property														Return _yAcceleration													End
	Method yAcceleration:Void(yAccelerationNew:Float) Property									_yAcceleration = yAccelerationNew										End
	
	Method xMaxVelocity:Float() Property														Return _xMaxVelocity													End
	Method yMaxVelocity:Float() Property														Return _yMaxVelocity													End
	
	Method xDisplacement:Int() Property															Return _xDisplacement													End
	Method yDisplacement:Int() Property															Return _yDisplacement													End
	
	Method SetMaxVelocity:Void(x:Float, y:Float)
		_xMaxVelocity = x
		_yMaxVelocity = y
	End
	
Private
	Global juggler := New Juggler<Velocity>
	Global unit:Int = UNIT_FRAMES				'not implemented yet

	Field _xVelocity:Float, _yVelocity:Float
	Field _xAcceleration:Float, _yAcceleration:Float
	Field _xMaxVelocity:Float, _yMaxVelocity:Float
	Field _xDisplacement:Int, _yDisplacement:Int
End



Class VelocityComponent Extends EntityComponent<IVelocity> Implements IVelocity

Public
	Method xVelocity:Float() Property															Return _velocity.xVelocity												End
	Method xVelocity:Void(xVelocityNew:Float) Property											_velocity.xVelocity = xVelocityNew										End
	Method yVelocity:Float() Property															Return _velocity.yVelocity												End
	Method yVelocity:Void(yVelocityNew:Float) Property											_velocity.yVelocity = yVelocityNew										End
	Method xAcceleration:Float() Property														Return _velocity.xAcceleration											End
	Method xAcceleration:Void(xAccelerationNew:Float) Property									_velocity.xAcceleration = xAccelerationNew								End
	Method yAcceleration:Float() Property														Return _velocity.yAcceleration											End
	Method yAcceleration:Void(yAccelerationNew:Float) Property									_velocity.yAcceleration = yAccelerationNew								End
	Method xMaxVelocity:Float() Property														Return _velocity.xMaxVelocity											End
	Method yMaxVelocity:Float() Property														Return _velocity.yMaxVelocity											End
	Method xDisplacement:Int() Property															Return _velocity.xDisplacement											End
	Method yDisplacement:Int() Property															Return _velocity.yDisplacement											End
	Method SetMaxVelocity:Void(x:Float, y:Float)												_velocity.SetMaxVelocity(x, y)											End
	
	Method Destroy:Void()
		_velocity.Destroy()
	End
	
Private
	Field _velocity := New Velocity()
End



Const V_2:Int  = %0000010
Const V_4:Int  = %0000100
Const V_8:Int  = %0001000
Const V_16:Int = %0010000
Const V_32:Int = %0100000
Const V_64:Int = %1000000



Class MyVelocityComponent' Extends EntityComponent 'Implements IVelocity, IJuggleable			'TODO replace above with this

Public
	Method xVelocity:Float() Property Return xvNominal End
	Method xVelocity:Void(xVelocityNew:Float) Property
		'TODO
	End
	
	Method yVelocity:Float() Property Return yvNominal End
	Method yVelocity:Void(yVelocityNew:Float) Property
		'TODO
	End

Private
	Field xvNominal:Float
	Field yvNominal:Float
	Field xvActual:Int
	Field yvActual:Int
	Field xvFractional:Int
	Field yvFractional:Int
	
	Field xRemainder:Float
	Field yRemainder:Float
End



Function UpdateVelocities:Void(timePassed:Int = -1)
	If timePassed = -1 Then timePassed = Tick()
	Velocity.juggler.Juggle(timePassed)
End